import { saveAs } from 'file-saver';
import ExcelJS from 'exceljs';

type Column = {
  key: string;
  dataIndex: string;
  title: string;
  width?: number;
};

type MergeCell = {
  startCell: string; // 开始合并的单元格
  endCell: string; // 结束合并的单元格
  value: string; // 合并单元格的值
  style: any; // 合并单元格样式
  transfer: (cell: any) => void; // 合并单元格样式转换函数
};

type Options = {
  data: any[];
  fileName: string;
  header: Column[];
  ortherData: any[]; // 其他数据
  mergeCellsArr: MergeCell[]; // 合并单元格数组
};

export default async function downloadTableToExcel(options: Options) {
  const { data, fileName, header, ortherData = [], mergeCellsArr } = options;

  const workbook = new ExcelJS.Workbook();
  const worksheet = workbook.addWorksheet('Sheet1');

  // 设置表头
  const headerKeys = header.map(col => col.dataIndex);
  worksheet.addRow(header.map(col => col.title)); // 添加表头行

  // 设置表头样式（加粗和居中）
  header.forEach((col, index) => {
    const cell = worksheet.getCell(1, index + 1); // 表头第一行
    cell.font = { bold: true };
    cell.alignment = { horizontal: 'center' };
    cell.fill = {
      fillType: 'pattern',
      pattern: 'solid',
      fgColor: { argb: 'FFCCCCCC' } // 灰色背景
    };
    worksheet.getColumn(index + 1).width = col.width ? col.width / 7 : 10; // 设置列宽
  });

  // 添加数据行
  [...data, ...ortherData].forEach(item => {
    worksheet.addRow(headerKeys.map(key => item[key]));
  });

  // 给数据行设置样式（居中）
  [...data, ...ortherData].forEach((item, rowIndex) => {
    headerKeys.forEach((key, colIndex) => {
      const cell = worksheet.getCell(rowIndex + 2, colIndex + 1); // 数据行从第二行开始
      cell.alignment = { horizontal: 'center' };
    });
  });

  // 合并单元格
  mergeCellsArr?.forEach(item => {
    worksheet.mergeCells(`${item.startCell}:${item.endCell}`);
    // 设置合并后单元格的样式
    const mergedCell = worksheet.getCell(item.startCell); // 获取合并后的单元格
    mergedCell.alignment = { horizontal: 'center', ...(item?.style || {}) }; // 合并后单元格居中
    mergedCell.value = item.value; // 设置合并后单元格的标题
    item.transfer && item.transfer(mergedCell); // 转换合并后单元格的样式
  });

  // 导出 Excel 文件
  const buffer = await workbook.xlsx.writeBuffer();
  const blob = new Blob([buffer], { type: 'application/octet-stream' });
  saveAs(blob, fileName);
}
